import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;

import processing.core.PImage;


public class ArtistBreakdown 
{
	//Instance variables.
	double male;
	double female;
	int totalUsers;
	double averageAge;
	String artistName;
	String artistID; 
	
	int[] countryCount;	//list where the index matches the countries index in the country list (GLOBAL.ALL_Countries)
	int[] ageCount;	//age count where the age is the index
	int[] topCountries = {0, 0, 0};	//Stores indexes of top 3 countries
	PImage[] topCountryImages;
	
	//Last FM Data
	String[] topTracks;		
	int[] similarArtists;	//indexes of similarArtists (in reference to radioGaGa.ArtistList)
	String artistInfo;
	
	//Default Constructor
	public ArtistBreakdown()
	{
		male = 0;
		female = 0;
		int[] countryCount = new int[GLOBAL.ALL_COUNTRIES.size()];
		int[] ageCount = new int[66];
	}
	
	//The real constructor!!!
	public ArtistBreakdown(ArtistData currentArtist)
	{
		male = 0;
		female = 0;
		countryCount = new int[GLOBAL.ALL_COUNTRIES.size()];
		ageCount = new int[66];
		totalUsers = currentArtist.userReferences.size();
		artistName = currentArtist.getName();
		artistID = currentArtist.getID(); 
		
		calculateTotals(currentArtist); //function to find totals for males & females, countries, & ages.
	}
	ArtistData temp;
	private void calculateTotals(ArtistData theArtist) {
		averageAge=0;
		//Parse all users to gather overall data
		//for(int x=0; x<theArtist.getUserListSize(); ++x) 
		for(int x=0; x < theArtist.userReferences.size(); ++x)
		{
			incrementGender(theArtist.getUser(x).getSexInt());		//GENDER
			incrementCountry(theArtist.getUser(x).getCountry());	//COUNTRY
			incrementAge(theArtist.getUser(x).getAgeInt());			//AGE
			
			//Add user in valid age range to averageAge
			if(theArtist.getUser(x).getAgeInt() > 12 && theArtist.getUser(x).getAgeInt() < 66)
				averageAge += theArtist.getUser(x).getAgeInt();
		}
		averageAge = averageAge/totalUsers;
		findTopCountries();	//Find the indexes of the top 3 countries.
		temp = theArtist;
	}
	
	private void incrementGender(int g) {
		if(g == 1)
			female++;
		else
			male++;
	}
	
	private void incrementCountry(String c) {
		if(countryCount==null)
			return;
		
		int index = GLOBAL.ALL_COUNTRIES.indexOf(c);
		if(index > -1)
			countryCount[index]++;
	}
	
	private void incrementAge(int a) {
		if(a < 13 || a > 65) {
			return;
		}
		
		ageCount[a]++;
	}
	
	private void findTopCountries() {
		if(countryCount == null)
			return;
		
		double top;
		int topIndex;
		double topOld = Double.MAX_VALUE;
		
		for(int x=0; x<topCountries.length; ++x) {
			top = 0;
			topIndex = 0;
			
			for(int y=0; y<countryCount.length; ++y) {
				if(countryCount[y] > top && countryCount[y] < topOld) {
					top = countryCount[y];
					topIndex = y;
				}
			}
			topCountries[x] = topIndex;
			topOld = countryCount[topIndex];
		}
	}
	
	public int getPercentFemale() {
		return (int) round(female/totalUsers);
	}
	
	public int getPercentMale() {
		return (int) round(male/totalUsers);
	}
	
	//Get percentage of country at index i
	private int getPercentCountry(int i) {
		return (int) round((double) countryCount[i] / (double) totalUsers);
	}
	
	//Get top countrys
	//	if num = 0		#1 Country
	//	if num = 1		#2 Country
	//	...ect. up to topCountries.length
	public int getPercentTopCountry(int num) {
		if(num > 2 || num < 0)
			return -1;
		
		return getPercentCountry(topCountries[num]);
	}

	public double getAverageAge() {
		return averageAge;
	}
	
	public String getTopCountry(int num) {
		if(num < 0 || num > 2)
			return "";
		
		return GLOBAL.ALL_COUNTRIES.get(topCountries[num]);
	}
	
	//round input to 2 decimal places
	private double round(double d) {
        return (double) Math.round(d * 100);
	}
	
	private void getLastFmData() {
		topTracks = GLOBAL.LAST_FM.getTopTrackNames(artistName);
		similarArtists = GLOBAL.LAST_FM.getSimilarArtists(artistName);

		if(artistID != null)
			artistInfo = LastfmAPI.showArtistInfo(artistID); //use ID for name IGG
		else 
			artistInfo = LastfmAPI.showArtistInfo(artistName);

		
		int i = artistInfo.indexOf("1)"); 
		if(i > -1) {
			artistInfo = artistInfo.substring(i+3);
		}
		
		//Remove html tags from artist info & add new lines
		artistInfo = removeHTML(artistInfo);
		artistInfo = breakString(artistInfo);
	}
	
	//Get top track at index 'num'
	public String getTopTrack(int num) {
		if(topTracks == null)
			getLastFmData();	//use LastFM API to retrieve additional artist data.
		
		if(topTracks[num] == null) {
			return "";
		}
		
		if(topTracks[num].length() > 19) {
			return topTracks[num].substring(0, 19) + "...";
		}
		
		return topTracks[num];
	}
	
	//Get similar artist at index 'num'
	public int getSimilarArtist(int num) {
		if(similarArtists == null)
			getLastFmData();	//use LastFM API to retrieve additional artist data.
		
		return similarArtists[num];
	}
	
	public String getArtistInfo() {
		return artistInfo;
	}
	
	private String removeHTML(String text){
		int index1 = text.indexOf("<");
		int index2 = text.indexOf(">");
		
		while(index1 > -1) {
			if(index2 == text.length()-1)
				index2--;
				
			text = text.substring(0, index1) + text.substring(index2+1);
			index1 = text.indexOf("<");
			index2 = text.indexOf(">");
		}
		
		return text;
	}
	
	private String breakString(String text) {
		if(text.length() < 20)
			return text;
		
		int maxLength = 70;
		int index1 = text.indexOf(" ", maxLength);
		
		while(index1 > -1) {
			text = text.substring(0, index1) + "\n" + text.substring(index1+1);
			maxLength += 70;
			index1 = text.indexOf(" ", maxLength);
		}
		
		text = text.replaceAll("&amp;", "&");
		text = text.replaceAll("&quot;", "\"");
		text = text.replaceAll("&uacute;", "u");
		
		return text;
	}
	
	public PImage getTopCountryImage(int num) {
		if(topCountryImages == null) {
			topCountryImages = new PImage[3];
			try {
				topCountryImages[0] = GLOBAL.processing.loadImage(getTopCountry(0).toLowerCase() + ".gif");
			} catch(Exception e) {
				topCountryImages[0] = GLOBAL.processing.loadImage("unknown.gif");
			}
			try { 
				topCountryImages[1] = GLOBAL.processing.loadImage(getTopCountry(1).toLowerCase() + ".gif");
			} catch(Exception e) {
				topCountryImages[1] = GLOBAL.processing.loadImage("unknown.gif");
			}
			try {
				topCountryImages[2] = GLOBAL.processing.loadImage(getTopCountry(2).toLowerCase() + ".gif");
			} catch(Exception e) {
				topCountryImages[2] = GLOBAL.processing.loadImage("unknown.gif");
			}
		}
		
		return topCountryImages[num];
	}
}
